<template>
  <div class="lessonPlanning">
    <el-form label-position="top" :model="formData">
      <div class="rightBtn" @click="magicWandIn">
        <img :src="magicWand" alt="" srcset="" />
        填入示例
      </div>
      <div v-for="(item, i) in prompts || []" :key="i">
        <!-- 文本 -->
        <el-form-item v-if="item[0] === 'text'">
          <template #label>
            <div class="labelBox">
              <span class="title">
                <span v-if="item[4] === '1'" class="require">* </span>
                {{ item[1] }}</span
              >
            </div>
          </template>
          <el-input v-model="formData[i]" type="textarea" :rows="item[3]" :placeholder="item[2]"></el-input>
        </el-form-item>
        <!-- 下拉框 -->
        <el-form-item v-if="item[0] === 'select'">
          <template #label>
            <div class="labelBox">
              <span class="title">
                <span v-if="item[4] === '1'" class="require">* </span>
                {{ item[1] }}</span
              >
            </div>
          </template>

          <el-select v-model="formData[i]" :placeholder="item[2]" size="large" style="width: 100%">
            <el-option v-for="(option, j) in item[3]" :key="j" :label="option.name" :value="option.name" />
          </el-select>
        </el-form-item>

        <!-- 树形结构 -->
        <el-form-item v-if="item[0] === 'tree'">
          <template #label>
            <div class="labelBox">
              <span class="title">
                <span v-if="item[4] === '1'" class="require">* </span>
                {{ item[1] }}</span
              >
            </div>
          </template>

          <el-cascader
            v-model="formData[i]"
            :options="state.unitList"
            :props="state.propsObj"
            clearable
            size="large"
            style="width: 100%"
          />
        </el-form-item>
        <!-- 纯上传 -->
        <el-form-item v-if="item[0] === 'file'">
          <template #label>
            <div class="labelBox">
              <span class="title">
                <span v-if="item[4] === '1'" class="require">* </span>
                {{ item[1] }}</span
              >
            </div>
          </template>

          <el-upload
            :headers="{ Authorization: `Bearer ${getStorage('token')}` }"
            class="upload-demo"
            list-type="picture-card"
            :action="uploadUrlBotId(botId)"
            :limit="1"
            :file-list="state.files[i]"
            :before-upload="audioBeforeUpload"
            :on-success="res => audioUploadSuccess(res, item, i)"
            :on-preview="handlePictureCardPreview"
            :on-remove="file => handleRemove(file, i)"
            :on-exceed="handleExceed"
          >
            <img :src="uploadAddCom" class="file-btn" @click="handUrl(i)" alt="" />
            <template #file="{ file }">
              <el-image v-if="state.files[i][0]" :src="state.files[i][0].url">
                <template #error>
                  <div class="image-slot">
                    <img class="img" :src="getUrlSuffix(i, 0)" alt="" srcset="" />
                  </div>
                </template>
              </el-image>
              <span class="el-upload-list__item-actions">
                <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file, i)">
                  <el-icon><Delete /></el-icon>
                </span>
              </span>
            </template>
          </el-upload>
        </el-form-item>
        <!-- 文本+上传 -->
        <el-form-item v-if="item[0] === 'fileinput'">
          <template #label>
            <div class="labelBox">
              <span class="title">
                <span v-if="item[4] === '1'" class="require">* </span>
                {{ item[1] }}</span
              >
            </div>
          </template>
          <div class="fileBoxContent">
            <el-input
              v-model="formData[i]"
              :disabled="state.audioPath ? true : false"
              class="link-input"
              type="textarea"
              :placeholder="item[2]"
              :rows="item[3]"
              @input="handUrl(i)"
            >
            </el-input>
            <el-upload
              list-type="picture-card"
              :headers="{ Authorization: `Bearer ${getStorage('token')}` }"
              :action="uploadUrlBotId(botId)"
              :limit="1"
              :file-list="state.files[i]"
              :before-upload="audioBeforeUpload"
              :on-success="res => audioUploadSuccess(res, item, i)"
              :on-preview="handlePictureCardPreview"
              :on-remove="file => handleRemove(file, i)"
              :on-exceed="handleExceed"
            >
              <img :src="uploadAddCom" class="file-btn" @click="handUrl(i)" alt="" />
              <template #file="{ file }">
                <el-image v-if="state.files[i][0]" :src="state.files[i][0].url" fit="scale-down">
                  <template #error>
                    <div class="image-slot">
                      <img class="img" :src="getUrlSuffix(i, 0)" alt="" srcset="" />
                    </div>
                  </template>
                </el-image>
                <span class="el-upload-list__item-actions">
                  <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file, i)">
                    <el-icon><Delete /></el-icon>
                  </span>
                </span>
              </template>
            </el-upload>
          </div>
        </el-form-item>
        <!-- 上传成绩单 -->
        <el-form-item v-if="item[0] === 'fileupload'">
          <template #label>
            <div class="labelBox">
              <span class="title">
                <span v-if="item[4] === '1'" class="require">* </span>
                {{ item[1] }}</span
              >
            </div>
          </template>
          <el-upload
            class="upload-Transcript"
            drag
            :limit="1"
            :headers="{ Authorization: `Bearer ${getStorage('token')}` }"
            :action="uploadXlsxBotId(botId)"
            :before-upload="audioBeforeUpload1"
            :on-success="res => audioUploadSuccess(res, item, i)"
            :on-remove="file => handleRemove(file, i)"
            :on-exceed="handleExceed"
          >
            <img :src="uploadTranscript" :disabled="state.linkUrl ? true : false" @click="handUrl(i)" alt="" />
            <div class="el-upload__text">
              <span style="color: #ff8500">点击上传 </span
              >{{ getChineseNameFromUrl(item[5]) == '学生成绩单模板.xlsx' ? '成绩单' : '学生信息' }}
            </div>
          </el-upload>

          <!-- 根据类型下载模板：1. 听力音频模板，2. 成绩单模板 -->
          <div class="file-con-moban">
            <img :src="xlsxSvg" alt="" srcset="" />
            <!-- <span class="file-path">学生成绩单模板.xlsx</span> -->
            <span class="file-path">{{ item[5] ? getChineseNameFromUrl(item[5]) : '' }}</span>
            <span class="file-del" @click="fileDownload(item[5], item[5] ? getChineseNameFromUrl(item[5]) : '')"
              >点击下载</span
            >
          </div>
        </el-form-item>
      </div>

      <el-dialog v-model="state.dialogVisible" width="1000px">
        <img w-full style="width: 900px" :src="state.linkUrl" alt="Preview Image" />
      </el-dialog>

      <el-form-item>
        <div class="createBtn" @click="sendCreate">{{ rightExt.botFlag == '11' ? '开始解析' : '生成' }}</div>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import _ from 'lodash';
import magicWand from '@/assets/ai/magicWand.svg';
import { getTree, getStorage } from '@/utils';
import { ElLoading, ElMessage } from 'element-plus';
import { cloneDeep, each, forIn } from 'lodash';
import { reactive, toRefs, watch } from 'vue';
import uploadAddCom from '@/assets/ai/uploadAddCom.svg';
import uploadTranscript from '@/assets/ai/upload.svg';
import xlsxSvg from '@/assets/ai/xlsx.svg';
import fileType from '@/assets/fileTypes/port';

import { uploadFileGet, uploadUrlBotId, uploadXlsxBotId } from '@/services/file';
import { chapterGet } from '@/services/chat';

import { useAppStore } from '@/store/modules/app';

const props = defineProps({
  prompts: Array,
  botId: String,
  rightExt: Object,
  subjectList: Array,
  gradeList: Array,
  versionList: Array,
});

const { prompts } = toRefs(props);

const state = reactive({
  // 预览
  dialogVisible: false,
  linkUrl: '',
  // 上传ing
  loadingInstance: false,
  // 根据下标存储上传的files
  files: {},
  // 文件类型
  wolds: 'txt,doc,docx,pdf,ppt,pptx,xlsx,xls',
  imgs: 'jpg,jpeg,png,gif,webp,svg',
  audios: 'mp3,m4a,wav,webm,amr',
  videos: 'mp4,mov,mpeg,mpga',

  // 单元名称列表
  unitList: [],
  grade: '3',
  subject: 'a',
  version: '',
  bookVersion: 'v1',
  propsObj: { checkStrictly: false, emitPath: false, label: 'label', value: 'label' },
});
const formData = reactive([]);

watch(
  () => formData,
  val => {
    if (!_.isEmpty(val) && props.rightExt) {
      if (props.rightExt.botFlag === '8') {
        const { code: gradeCode } = _.find(props.gradeList, { name: val[0] }) || {};
        state.grade = gradeCode;
        const { code: subjectCode } = _.find(props.subjectList, { name: val[1] }) || {};
        state.subject = subjectCode;
        const { code: versionCode } = _.find(props.versionList, { title: val[2] }) || {};
        state.version = versionCode;
        getUnitList();
      }
    }
  },
  { deep: true, immediate: true },
);

// 获取章节目录
const getUnitList = async () => {
  if (state.grade && state.subject && state.version) {
    const args = {
      grade: state.grade,
      subject: state.subject,
      publishers: state.version,
      status: '1',
      // bookVersion: state.bookVersion,
    };
    const { data } = await chapterGet(args);
    if (data) {
      // state.unitList = data;
      const tableData = _.map(_.sortBy(data, 'sortNum'), v => ({
        ...v,
        pid: v.pid === '0' ? null : v.pid,
        name: v.title,
      }));
      state.unitList = getTree(tableData) || [];
    }
  } else {
    state.unitList = [];
    formData[3] = '';
  }
};

const emits = defineEmits(['query']);
const sendCreate = () => {
  const deep = cloneDeep(prompts.value);
  const fileDeep = cloneDeep(state.files);
  // 一次性收集所有没填的必填项
  const errors = [];

  deep.forEach((v, i) => {
    if (['text', 'select', 'tree'].includes(v[0])) {
      const label = v[1]; // 假设 v[1] 是字段名
      const required = v[4] === '1'; // 必填标记
      const value = formData[i];
      if (required && (value === undefined || value === null || value === '')) {
        errors.push(label);
      }
    }
    if (['file', 'fileupload'].includes(v[0])) {
      // 纯上传
      if (v[4] === '1' && (!fileDeep[0] || fileDeep[0].length === 0)) {
        errors.push(v[1]);
      }
    }

    if (['fileinput'].includes(v[0]) && v[4] === '1') {
      // 上传+输入
      const value = formData[i];
      if ((!fileDeep[0] || fileDeep[0].length === 0) && !value) {
        errors.push(v[1]);
      }
    }
  });

  if (errors.length > 0) {
    ElMessage.warning('请完善：' + errors.join('、'));
    return;
  }
  //  处理图片
  const files = [];
  forIn(fileDeep, v => {
    if (v[0].url) {
      files.push(v[0].url);
    }
  });
  // forIn(fileDeep, (v, key) => {
  //   files[key] = v.map(v => v.url).join(',');
  // });
  // 全部校验通过
  // console.log('formData =======> ', formData);
  emits('query', formData, files.join(','));
};

// 填入示例
const magicWandIn = () => {
  each(prompts.value, (item, i) => {
    formData[i] = item[5];
  });
};

const getUrlSuffix = (uploadIndex, fileIndex) => {
  const files = state.files[uploadIndex];
  if (Array.isArray(files)) {
    const filename = files[fileIndex].url;
    const suffix = filename.substring(filename.lastIndexOf('.') + 1); // "txt"
    return fileType[suffix.toLocaleLowerCase()];
  }
  return null;
};

const isIMG = filename => {
  const suffix = filename.substring(filename.lastIndexOf('.') + 1); // "txt"
  const imgs = 'jpg,jpeg,png,gif,webp,svg';
  return imgs.includes(suffix);
};

// 预览
const handUrl = i => {
  // state.fileNumber = i;
  // state.values[i] = state.linkUrl;
};

// 下载模板
const fileDownload = (url, filename) => {
  try {
    const { exts } = window.top.parent;
    if (exts) {
      exts.download(url, {
        filename,
        saveAs: false,
        openFolderWhenDone: '',
      });
    } else {
      window.open(url);
    }
  } catch (error) {
    window.open(url);
  }
};

// 文件上传
const audioBeforeUpload = rawFile => {
  if (props.rightExt.botFlag == '1' || props.rightExt.botFlag == '11' || props.rightExt.canshuType == '4') {
    const fileType = ['jpg', 'png', 'jpeg'];
    const fileExtension = _.last(rawFile.name.split('.'));
    if (!fileType.includes(fileExtension)) {
      ElMessage.error(`请上传${fileType.join(',')}格式的图片`);
      return Promise.reject();
    }
  }

  const isLt15M = rawFile.size / 1024 / 1024 < 15;
  if (!isLt15M) {
    ElMessage.error('上传的文件大小不能超过 15MB!');
    return Promise.reject();
  }
  // if (!_.includes(['mp3'], _.last(rawFile.name.split('.')))) {
  //   ElMessage.error('音频文件格式MP3');
  //   return Promise.reject();
  // }
  state.loadingInstance = ElLoading.service({
    lock: true,
    text: '上传中...',
    spinner: 'Loading',
  });
};

const handleExceed = files => {
  ElMessage.warning('只能上传一个图片或文件');
};

// 文件上传
const audioBeforeUpload1 = rawFile => {
  const isLt15M = rawFile.size / 1024 / 1024 < 15;
  if (!isLt15M) {
    ElMessage.error('上传的文件大小不能超过 15MB!');
    return Promise.reject();
  }
  const { name } = rawFile;
  // 验证文件类型
  const fileExtension = name.substring(name.lastIndexOf('.')).toLowerCase();
  const allowedExtensions = ['.xlsx'];

  if (!allowedExtensions.includes(fileExtension)) {
    ElMessage.error('只支持上传xlsx格式的文件');
    return Promise.reject();
  }
  // if (!_.includes(['xlsx'], _.last(rawFile.name.split('.')))) {
  //   ElMessage.error('请上传xlsx文件');
  //   return Promise.reject();
  // }
  state.loadingInstance = ElLoading.service({
    lock: true,
    text: '上传中...',
    spinner: 'Loading',
  });
};

// 文件上传成功
const audioUploadSuccess = (res, item, i) => {
  const { errCode, data } = res;
  if (errCode === 0) {
    if (state.loadingInstance) {
      state.loadingInstance.close();
    }
    // // state.audioPath = `${ossGetImg}${data.key}`;
    // // 存储到对应的里面去
    if (!state.files[i]) {
      state.files[i] = [];
    }
    // 根据文件后缀判断类型
    const houzhui = _.last(data.filePath.split('.'));
    let type = '';
    if (_.includes(state.wolds, houzhui.toLowerCase())) {
      type = 'document';
    }
    if (_.includes(state.imgs, houzhui.toLowerCase())) {
      type = 'image';
    }
    state.files[i].push({
      url: uploadFileGet(data.filePath),
      type,
      key: data.key,
      transfer_method: 'remote_url',
    });
  } else if (errCode === 500) {
    if (state.loadingInstance) {
      state.loadingInstance.close();
    }
    ElMessage.error('上传内容不能为空');
  }
};

// 文件删除

const handleRemove = (uploadFile, index) => {
  // 如果文件还未上传成功（没有 response），直接返回
  if (!uploadFile.response && !uploadFile.key) {
    return;
  }
  const fileKey = uploadFile.key || uploadFile.response.data.key;
  const deep = cloneDeep(state.files);
  const idx = state.files[index].findIndex(vx => vx.key === fileKey);
  if (idx >= 0) {
    deep[index].splice(idx, 1);
    state.files = deep;
  }
};

const handlePictureCardPreview = uploadFile => {
  state.linkUrl = uploadFile.url;
  state.dialogVisible = true;
};

// 解析文件名称
const getChineseNameFromUrl = url => {
  if (!url) return '';

  // 1. 解码URL（处理编码后的中文，如%E5%AD%A6%E7%94%9F）
  const decodedUrl = decodeURIComponent(url);

  // 2. 分割URL获取路径部分
  const path = decodedUrl.split('/').pop();
  if (!path) return '';
  return path;

  // 3. 去除文件扩展名和URL参数
  const nameWithExt = path.split('?')[0]; // 去除?后的参数
  const extIndex = nameWithExt.lastIndexOf('.');
  const nameWithoutExt = extIndex > 0 ? nameWithExt.substring(0, extIndex) : nameWithExt;

  // 4. 提取中文名称（过滤非中文字符）
  const chineseName = nameWithoutExt.replace(/[^\u4e00-\u9fa5]/g, '');
  return chineseName || nameWithoutExt; // 无中文时返回原名称
};
</script>

<style lang="scss">
@use './lessonPlanning.scss';
</style>
